const _ = require('lodash');
const moment = require('moment');
const { setupLogger } = require('../utils/logger');

class AnalysisService {
  constructor() {
    this.logger = setupLogger();
  }

  async processData(rawData) {
    try {
      this.logger.info(`开始处理数据，原始数据量: ${rawData.length}`);
      
      // 数据清洗和标准化
      const cleanedData = this.cleanData(rawData);
      
      // 分类处理数据
      const categorizedData = this.categorizeData(cleanedData);
      
      // 分析token信息
      const tokenAnalysis = this.analyzeTokens(categorizedData);
      
      // 分析聪明钱信息
      const smartMoneyAnalysis = this.analyzeSmartMoney(categorizedData);
      
      // 市场数据分析
      const marketAnalysis = this.analyzeMarketData(categorizedData);
      
      // 趋势分析
      const trendAnalysis = this.analyzeTrends(categorizedData);
      
      // 风险评估
      const riskAnalysis = this.analyzeRisks(categorizedData);
      
      const processedData = {
        tokens: tokenAnalysis,
        smartMoney: smartMoneyAnalysis,
        marketData: marketAnalysis,
        trends: trendAnalysis,
        risks: riskAnalysis,
        summary: this.generateSummary(tokenAnalysis, smartMoneyAnalysis, marketAnalysis),
        lastProcessed: new Date().toISOString(),
        dataCount: {
          total: rawData.length,
          cleaned: cleanedData.length,
          tokens: tokenAnalysis.length,
          smartMoney: smartMoneyAnalysis.length
        }
      };
      
      this.logger.info(`数据处理完成，生成代币分析: ${tokenAnalysis.length} 条，聪明钱分析: ${smartMoneyAnalysis.length} 条`);
      
      return processedData;
    } catch (error) {
      this.logger.error('数据处理失败:', error);
      throw error;
    }
  }

  cleanData(rawData) {
    return rawData.filter(item => {
      // 基本数据验证
      if (!item || typeof item !== 'object') return false;
      if (!item.source || !item.type) return false;
      if (!item.timestamp) return false;
      
      // 价格数据验证
      if (item.price !== undefined && (isNaN(item.price) || item.price < 0)) {
        item.price = 0;
      }
      
      // 交易量数据验证
      if (item.volume24h !== undefined && (isNaN(item.volume24h) || item.volume24h < 0)) {
        item.volume24h = 0;
      }
      
      // 市值数据验证
      if (item.marketCap !== undefined && (isNaN(item.marketCap) || item.marketCap < 0)) {
        item.marketCap = 0;
      }
      
      return true;
    }).map(item => {
      // 标准化时间戳
      if (item.timestamp) {
        item.timestamp = moment(item.timestamp).toISOString();
      }
      
      // 标准化符号
      if (item.symbol) {
        item.symbol = item.symbol.toUpperCase();
      }
      
      // 添加唯一ID
      item.id = this.generateId(item);
      
      return item;
    });
  }

  categorizeData(cleanedData) {
    return {
      tokens: cleanedData.filter(item => 
        ['market_data', 'token_search', 'token_price', 'token_detail', 'hot_token', 'new_token', 'trending_coin'].includes(item.type)
      ),
      smartMoney: cleanedData.filter(item => 
        ['smart_money', 'wallet_analysis', 'holder_analysis'].includes(item.type)
      ),
      marketData: cleanedData.filter(item => 
        ['24hr_ticker', 'ticker', 'exchange_info', 'global_data', 'defi_data'].includes(item.type)
      ),
      social: cleanedData.filter(item => 
        ['tweet', 'user_tweet'].includes(item.type)
      ),
      trading: cleanedData.filter(item => 
        ['order_book', 'trade', 'kline', 'candlestick'].includes(item.type)
      ),
      onChain: cleanedData.filter(item => 
        ['onchain_analysis', 'pool_info', 'network_pool'].includes(item.type)
      )
    };
  }

  analyzeTokens(categorizedData) {
    const tokens = categorizedData.tokens;
    const tokenMap = new Map();
    
    // 按symbol分组并合并数据
    tokens.forEach(token => {
      const symbol = token.symbol || 'UNKNOWN';
      
      if (!tokenMap.has(symbol)) {
        tokenMap.set(symbol, {
          symbol: symbol,
          name: token.name || symbol,
          sources: [],
          prices: [],
          volumes: [],
          marketCaps: [],
          priceChanges: [],
          metrics: {},
          riskFactors: [],
          lastUpdated: token.timestamp
        });
      }
      
      const tokenData = tokenMap.get(symbol);
      tokenData.sources.push(token.source);
      
      if (token.price > 0) {
        tokenData.prices.push({
          value: token.price,
          source: token.source,
          timestamp: token.timestamp
        });
      }
      
      if (token.volume24h > 0) {
        tokenData.volumes.push({
          value: token.volume24h,
          source: token.source,
          timestamp: token.timestamp
        });
      }
      
      if (token.marketCap > 0) {
        tokenData.marketCaps.push({
          value: token.marketCap,
          source: token.source,
          timestamp: token.timestamp
        });
      }
      
      if (token.priceChange24h !== undefined) {
        tokenData.priceChanges.push({
          value: token.priceChange24h,
          source: token.source,
          timestamp: token.timestamp
        });
      }
      
      // 收集其他指标
      if (token.holders) tokenData.metrics.holders = token.holders;
      if (token.liquidity) tokenData.metrics.liquidity = token.liquidity;
      if (token.transactions24h) tokenData.metrics.transactions24h = token.transactions24h;
      
      // 风险因素
      if (token.isHoneypot) tokenData.riskFactors.push('honeypot');
      if (token.isRugPull) tokenData.riskFactors.push('rug_pull');
      if (token.riskLevel && token.riskLevel !== 'low') tokenData.riskFactors.push(token.riskLevel);
    });
    
    // 计算聚合指标
    return Array.from(tokenMap.values()).map(token => {
      // 计算平均价格
      if (token.prices.length > 0) {
        token.avgPrice = _.meanBy(token.prices, 'value');
        token.priceRange = {
          min: _.minBy(token.prices, 'value').value,
          max: _.maxBy(token.prices, 'value').value
        };
      }
      
      // 计算平均交易量
      if (token.volumes.length > 0) {
        token.avgVolume24h = _.meanBy(token.volumes, 'value');
      }
      
      // 计算平均市值
      if (token.marketCaps.length > 0) {
        token.avgMarketCap = _.meanBy(token.marketCaps, 'value');
      }
      
      // 计算平均价格变化
      if (token.priceChanges.length > 0) {
        token.avgPriceChange24h = _.meanBy(token.priceChanges, 'value');
      }
      
      // 计算数据源数量
      token.sourceCount = _.uniq(token.sources).length;
      
      // 计算综合评分
      token.score = this.calculateTokenScore(token);
      
      // 分类
      token.category = this.categorizeToken(token);
      
      return token;
    }).sort((a, b) => (b.score || 0) - (a.score || 0));
  }

  analyzeSmartMoney(categorizedData) {
    const smartMoneyData = categorizedData.smartMoney;
    const walletMap = new Map();
    
    // 按地址分组并合并数据
    smartMoneyData.forEach(data => {
      const address = data.address || data.holderAddress || 'UNKNOWN';
      
      if (!walletMap.has(address)) {
        walletMap.set(address, {
          address: address,
          nickname: data.nickname,
          sources: [],
          pnlData: [],
          trades: [],
          holdings: [],
          metrics: {},
          tags: [],
          lastUpdated: data.timestamp
        });
      }
      
      const walletData = walletMap.get(address);
      walletData.sources.push(data.source);
      
      // PnL数据
      if (data.pnl7d !== undefined) {
        walletData.pnlData.push({
          period: '7d',
          value: data.pnl7d,
          source: data.source,
          timestamp: data.timestamp
        });
      }
      
      if (data.pnl30d !== undefined) {
        walletData.pnlData.push({
          period: '30d',
          value: data.pnl30d,
          source: data.source,
          timestamp: data.timestamp
        });
      }
      
      // 交易数据
      if (data.totalTrades) walletData.metrics.totalTrades = data.totalTrades;
      if (data.winRate) walletData.metrics.winRate = data.winRate;
      if (data.avgHoldTime) walletData.metrics.avgHoldTime = data.avgHoldTime;
      if (data.totalVolume) walletData.metrics.totalVolume = data.totalVolume;
      
      // 持仓数据
      if (data.balance && data.tokenSymbol) {
        walletData.holdings.push({
          token: data.tokenSymbol,
          balance: data.balance,
          value: data.value,
          percentage: data.percentage,
          timestamp: data.timestamp
        });
      }
      
      // 标签
      if (data.tags && Array.isArray(data.tags)) {
        walletData.tags.push(...data.tags);
      }
      if (data.isWhale) walletData.tags.push('whale');
      if (data.isSmartMoney) walletData.tags.push('smart_money');
    });
    
    // 计算聚合指标
    return Array.from(walletMap.values()).map(wallet => {
      // 计算平均PnL
      const pnl7dData = wallet.pnlData.filter(p => p.period === '7d');
      const pnl30dData = wallet.pnlData.filter(p => p.period === '30d');
      
      if (pnl7dData.length > 0) {
        wallet.avgPnl7d = _.meanBy(pnl7dData, 'value');
      }
      
      if (pnl30dData.length > 0) {
        wallet.avgPnl30d = _.meanBy(pnl30dData, 'value');
      }
      
      // 去重标签
      wallet.tags = _.uniq(wallet.tags);
      
      // 计算智能评分
      wallet.smartScore = this.calculateSmartScore(wallet);
      
      // 风险等级
      wallet.riskLevel = this.calculateRiskLevel(wallet);
      
      return wallet;
    }).sort((a, b) => (b.smartScore || 0) - (a.smartScore || 0));
  }

  analyzeMarketData(categorizedData) {
    const marketData = categorizedData.marketData;
    
    return {
      overview: this.calculateMarketOverview(marketData),
      exchanges: this.analyzeExchanges(marketData),
      defi: this.analyzeDefiMetrics(marketData),
      trends: this.analyzeMarketTrends(marketData),
      timestamp: new Date().toISOString()
    };
  }

  analyzeTrends(categorizedData) {
    const allData = [
      ...categorizedData.tokens,
      ...categorizedData.social,
      ...categorizedData.trading
    ];
    
    // 按时间排序
    const sortedData = allData.sort((a, b) => 
      new Date(a.timestamp) - new Date(b.timestamp)
    );
    
    // 分析价格趋势
    const priceTrends = this.analyzePriceTrends(sortedData);
    
    // 分析交易量趋势
    const volumeTrends = this.analyzeVolumeTrends(sortedData);
    
    // 分析社交媒体趋势
    const socialTrends = this.analyzeSocialTrends(categorizedData.social);
    
    return {
      price: priceTrends,
      volume: volumeTrends,
      social: socialTrends,
      timestamp: new Date().toISOString()
    };
  }

  analyzeRisks(categorizedData) {
    const risks = [];
    
    // 分析代币风险
    categorizedData.tokens.forEach(token => {
      if (token.isHoneypot) {
        risks.push({
          type: 'honeypot',
          severity: 'high',
          token: token.symbol,
          description: '检测到蜜罐代币'
        });
      }
      
      if (token.isRugPull) {
        risks.push({
          type: 'rug_pull',
          severity: 'critical',
          token: token.symbol,
          description: '检测到跑路风险'
        });
      }
      
      if (token.liquidity && token.liquidity < 10000) {
        risks.push({
          type: 'low_liquidity',
          severity: 'medium',
          token: token.symbol,
          description: '流动性过低'
        });
      }
    });
    
    return risks;
  }

  calculateTokenScore(token) {
    let score = 0;
    
    // 数据源多样性 (0-20分)
    score += Math.min(token.sourceCount * 4, 20);
    
    // 交易量 (0-25分)
    if (token.avgVolume24h) {
      if (token.avgVolume24h > 1000000) score += 25;
      else if (token.avgVolume24h > 100000) score += 20;
      else if (token.avgVolume24h > 10000) score += 15;
      else if (token.avgVolume24h > 1000) score += 10;
      else score += 5;
    }
    
    // 市值 (0-25分)
    if (token.avgMarketCap) {
      if (token.avgMarketCap > 1000000000) score += 25;
      else if (token.avgMarketCap > 100000000) score += 20;
      else if (token.avgMarketCap > 10000000) score += 15;
      else if (token.avgMarketCap > 1000000) score += 10;
      else score += 5;
    }
    
    // 价格稳定性 (0-15分)
    if (token.priceRange) {
      const volatility = (token.priceRange.max - token.priceRange.min) / token.avgPrice;
      if (volatility < 0.1) score += 15;
      else if (volatility < 0.3) score += 10;
      else if (volatility < 0.5) score += 5;
    }
    
    // 风险因素扣分
    score -= token.riskFactors.length * 10;
    
    return Math.max(0, Math.min(100, score));
  }

  calculateSmartScore(wallet) {
    let score = 0;
    
    // PnL表现 (0-40分)
    if (wallet.avgPnl7d > 0) score += 20;
    if (wallet.avgPnl30d > 0) score += 20;
    
    // 胜率 (0-25分)
    if (wallet.metrics.winRate) {
      score += wallet.metrics.winRate * 25;
    }
    
    // 交易频率 (0-20分)
    if (wallet.metrics.totalTrades) {
      if (wallet.metrics.totalTrades > 100) score += 20;
      else if (wallet.metrics.totalTrades > 50) score += 15;
      else if (wallet.metrics.totalTrades > 20) score += 10;
      else score += 5;
    }
    
    // 标签加分
    if (wallet.tags.includes('whale')) score += 10;
    if (wallet.tags.includes('early_adopter')) score += 5;
    
    return Math.max(0, Math.min(100, score));
  }

  calculateRiskLevel(wallet) {
    if (wallet.smartScore > 80) return 'low';
    if (wallet.smartScore > 60) return 'medium';
    if (wallet.smartScore > 40) return 'high';
    return 'very_high';
  }

  categorizeToken(token) {
    if (token.avgMarketCap > 1000000000) return 'large_cap';
    if (token.avgMarketCap > 100000000) return 'mid_cap';
    if (token.avgMarketCap > 10000000) return 'small_cap';
    return 'micro_cap';
  }

  calculateMarketOverview(marketData) {
    const globalData = marketData.filter(item => item.type === 'global_data');
    if (globalData.length === 0) return null;
    
    const latest = globalData[globalData.length - 1];
    return {
      totalMarketCap: latest.totalMarketCap,
      totalVolume: latest.totalVolume,
      marketCapChange24h: latest.marketCapChangePercentage24hUsd,
      activeCryptocurrencies: latest.activeCryptocurrencies,
      markets: latest.markets
    };
  }

  analyzeExchanges(marketData) {
    return marketData
      .filter(item => item.type === 'exchange')
      .map(exchange => ({
        name: exchange.name,
        trustScore: exchange.trustScore,
        volume24h: exchange.tradeVolume24hBtc,
        country: exchange.country
      }))
      .sort((a, b) => (b.volume24h || 0) - (a.volume24h || 0));
  }

  analyzeDefiMetrics(marketData) {
    const defiData = marketData.filter(item => item.type === 'defi_data');
    if (defiData.length === 0) return null;
    
    const latest = defiData[defiData.length - 1];
    return {
      defiMarketCap: latest.defiMarketCap,
      defiToEthRatio: latest.defiToEthRatio,
      tradingVolume24h: latest.tradingVolume24h,
      defiDominance: latest.defiDominance
    };
  }

  analyzeMarketTrends(marketData) {
    // 简化的趋势分析
    return {
      direction: 'neutral',
      strength: 'medium',
      confidence: 0.5
    };
  }

  analyzePriceTrends(data) {
    const priceData = data.filter(item => item.price > 0);
    if (priceData.length < 2) return { direction: 'neutral', strength: 'low' };
    
    const recent = priceData.slice(-10);
    const prices = recent.map(item => item.price);
    
    const firstPrice = prices[0];
    const lastPrice = prices[prices.length - 1];
    const change = (lastPrice - firstPrice) / firstPrice;
    
    return {
      direction: change > 0.05 ? 'up' : change < -0.05 ? 'down' : 'neutral',
      strength: Math.abs(change) > 0.1 ? 'high' : Math.abs(change) > 0.05 ? 'medium' : 'low',
      change: change
    };
  }

  analyzeVolumeTrends(data) {
    const volumeData = data.filter(item => item.volume24h > 0);
    if (volumeData.length < 2) return { direction: 'neutral', strength: 'low' };
    
    const recent = volumeData.slice(-10);
    const volumes = recent.map(item => item.volume24h);
    
    const avgVolume = _.mean(volumes);
    const recentAvg = _.mean(volumes.slice(-3));
    const change = (recentAvg - avgVolume) / avgVolume;
    
    return {
      direction: change > 0.1 ? 'up' : change < -0.1 ? 'down' : 'neutral',
      strength: Math.abs(change) > 0.2 ? 'high' : Math.abs(change) > 0.1 ? 'medium' : 'low',
      change: change
    };
  }

  analyzeSocialTrends(socialData) {
    const tweets = socialData.filter(item => item.type === 'tweet' || item.type === 'user_tweet');
    
    return {
      totalMentions: tweets.length,
      sentiment: this.calculateSentiment(tweets),
      topInfluencers: this.getTopInfluencers(tweets),
      trendingTopics: this.getTrendingTopics(tweets)
    };
  }

  calculateSentiment(tweets) {
    // 简化的情感分析
    const positiveWords = ['bullish', 'moon', 'pump', 'buy', 'hodl', 'diamond'];
    const negativeWords = ['bearish', 'dump', 'sell', 'crash', 'scam', 'rug'];
    
    let positiveCount = 0;
    let negativeCount = 0;
    
    tweets.forEach(tweet => {
      const content = (tweet.content || '').toLowerCase();
      positiveWords.forEach(word => {
        if (content.includes(word)) positiveCount++;
      });
      negativeWords.forEach(word => {
        if (content.includes(word)) negativeCount++;
      });
    });
    
    const total = positiveCount + negativeCount;
    if (total === 0) return 'neutral';
    
    const ratio = positiveCount / total;
    if (ratio > 0.6) return 'positive';
    if (ratio < 0.4) return 'negative';
    return 'neutral';
  }

  getTopInfluencers(tweets) {
    const influencers = new Map();
    
    tweets.forEach(tweet => {
      if (tweet.author && tweet.author.followers > 10000) {
        const username = tweet.author.username;
        if (!influencers.has(username)) {
          influencers.set(username, {
            username: username,
            followers: tweet.author.followers,
            tweets: 0,
            totalEngagement: 0
          });
        }
        
        const influencer = influencers.get(username);
        influencer.tweets++;
        influencer.totalEngagement += (tweet.metrics?.likes || 0) + (tweet.metrics?.retweets || 0);
      }
    });
    
    return Array.from(influencers.values())
      .sort((a, b) => b.totalEngagement - a.totalEngagement)
      .slice(0, 5);
  }

  getTrendingTopics(tweets) {
    const topics = new Map();
    const cryptoKeywords = ['bitcoin', 'btc', 'ethereum', 'eth', 'crypto', 'defi', 'nft', 'web3'];
    
    tweets.forEach(tweet => {
      const content = (tweet.content || '').toLowerCase();
      cryptoKeywords.forEach(keyword => {
        if (content.includes(keyword)) {
          topics.set(keyword, (topics.get(keyword) || 0) + 1);
        }
      });
    });
    
    return Array.from(topics.entries())
      .map(([topic, count]) => ({ topic, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 10);
  }

  generateSummary(tokens, smartMoney, marketData) {
    return {
      totalTokens: tokens.length,
      totalSmartWallets: smartMoney.length,
      topTokens: tokens.slice(0, 5).map(t => ({ symbol: t.symbol, score: t.score })),
      topSmartWallets: smartMoney.slice(0, 3).map(w => ({ 
        address: w.address.substring(0, 8) + '...', 
        score: w.smartScore 
      })),
      marketOverview: marketData.overview,
      generatedAt: new Date().toISOString()
    };
  }

  generateId(item) {
    const key = `${item.source}_${item.type}_${item.symbol || item.address || item.id || Date.now()}`;
    return Buffer.from(key).toString('base64').substring(0, 16);
  }
}

module.exports = new AnalysisService();

